package com.jpatest.demo.configuration;

import org.apache.curator.RetryPolicy;
import org.apache.curator.framework.CuratorFramework;
import org.apache.curator.framework.CuratorFrameworkFactory;
import org.apache.curator.framework.api.CuratorEvent;
import org.apache.curator.framework.api.CuratorEventType;
import org.apache.curator.framework.api.CuratorListener;
import org.apache.curator.framework.recipes.leader.LeaderSelector;
import org.apache.curator.framework.recipes.leader.LeaderSelectorListenerAdapter;
import org.apache.curator.retry.ExponentialBackoffRetry;
import org.apache.curator.x.discovery.ServiceDiscovery;
import org.apache.curator.x.discovery.ServiceDiscoveryBuilder;
import org.apache.curator.x.discovery.ServiceInstance;
import org.apache.curator.x.discovery.ServiceInstanceBuilder;
import org.apache.curator.x.discovery.details.JsonInstanceSerializer;
import org.apache.zookeeper.WatchedEvent;
import org.apache.zookeeper.Watcher;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;

import java.util.HashMap;
import java.util.Map;


//@Configuration
public class ZooKeeperConfiguration {
    private org.slf4j.Logger log = LoggerFactory.getLogger(this.getClass());

    @Value("${zk.url}")
    private String zkUrl;

    @Bean
    public CuratorFramework getCuratorFramework(){
        RetryPolicy retryPolicy = new ExponentialBackoffRetry(1000,3);
        CuratorFramework client = CuratorFrameworkFactory.newClient(zkUrl,retryPolicy);
        //添加一个监视监听器
        client.getCuratorListenable().addListener(new CuratorListener() {
            @Override
            public void eventReceived(CuratorFramework client, CuratorEvent curatorEvent) throws Exception {
                CuratorEventType type = curatorEvent.getType();
                if(type == CuratorEventType.WATCHED){
                    WatchedEvent event = curatorEvent.getWatchedEvent();
                    Watcher.Event.EventType eventType = event.getType();
                    log.info(eventType + ":" + event.getPath());
                    client.checkExists().watched().forPath(event.getPath());
                }
            }
        });
        client.start();
        try {
            registerService(client);
        } catch (Exception e) {
            e.printStackTrace();
        }

        //构造一个选举领导的监听器
//        LeaderSelectorListenerAdapter listener = new LeaderSelectorListenerAdapter() {
//            @Override
//            public void takeLeadership(CuratorFramework client) throws Exception {
//                log.info("get leadership!!!");
//            }
//        };
//        //启动选举领导
//        LeaderSelector selector = new LeaderSelector(client,"/schedule",listener);
//        selector.autoRequeue();
//        selector.start();
        return client;
    }

    protected void registerService(CuratorFramework client) throws Exception{
        //构造一个服务描述
        ServiceInstanceBuilder<Map> service = ServiceInstance.builder();
        service.address("127.0.0.1");
        service.port(8080);
        service.name("book");
        Map config = new HashMap();
        config.put("url","api/v3/book");
        service.payload(config);
        ServiceInstance<Map> instance = service.build();
        ServiceDiscovery<Map> serviceDiscovery = ServiceDiscoveryBuilder.builder(Map.class).client(client).serializer(new JsonInstanceSerializer<Map>(Map.class)).basePath("/service").build();
        //服务注册
        serviceDiscovery.registerService(instance);
        serviceDiscovery.start();
    }


}
